//Thingy starts at 100, 100, and has (by default) radius

/*
  To make a "string":
 
 1) start with a list of GREEN particles
 2) add each particle to otherParticle
 3) while doing that, add each particle to buffer, as well
 4) call strutList(buffer,myStrut) to add the struts to the strut list
 5) initialize greenStruts array, fill it with strut information
 6) clear buffer and return to 1) for RED and then BLUE
 */

/*
  To make (i.e.) a green triangle:
 
 1) Start with 3 particles, pA, pB, pC
 2) add to otherParticle
 3) add to buffer
 4) make new Strut(pA,pB); sim. for pA,pC, and pB,pC
 5) add struts to myStrut and greenStruts (or red or blue)
 
 */
/*
OR create levelstring, e.g.
  levelString += "particlesBegin\n";
  levelString += "particle,150,150,0.1,4.0,RED\n";
  levelString += "particle,260,150,0.1,4.0,RED\n";
  levelString += "particle,150,260,0.1,4.0,RED\n";
  levelString += "particle,160,160,0.1,4.0,RED\n";
  levelString += "particle,170,260,0.1,4.0,RED\n";
  levelString += "particlesEnd\n";
  levelString += "strutsBegin\n";
  levelString += "strut,0,1,RED\n";
  levelString += "strut,1,2,RED\n";
  levelString += "strut,2,0,RED\n";
  levelString += "strut,2,3,RED\n";
  levelString += "strut,3,4,RED\n";
  levelString += "strut,4,2,RED\n";
  levelString += "strutsEnd\n";
  float rad = 10500;
  int myNum = 200;
  Vector3d[] myVecs = new Vector3d[myNum/2];
  levelString += "wallBegin\n";
  for (int i=0; i<myNum/2; i++){
    myVecs[i] = new Vector3d(rad-rad*cos(TWO_PI*i/(myNum-1)),rad*sin(TWO_PI*i/(myNum-1)),0);
    levelString += "wallPoint,"+myVecs[i].x+","+myVecs[i].y+"\n";
  }
  levelString += "wallEnd\n";
  rad = 2000;
  myNum = 300;
  myVecs = new Vector3d[myNum/2];
  levelString += "wallBegin\n";
  for (int i=0; i<myNum/2; i++){
    myVecs[i] = new Vector3d(rad-rad*cos(TWO_PI*i/(myNum-1)),rad*sin(TWO_PI*i/(myNum-1)),0);
    levelString += "wallPoint,"+myVecs[i].x+","+myVecs[i].y+"\n";
  }
  levelString += "wallEnd\n";

*/

public void setLevelLocation(String ll){
  levelLocation = ll;
}

public void setLevelFromString(String ls){
  inputLevelString = ls;
}

//Begin level specification

void makeStruts(){
//irrelevant now
}  


void makeWalls(){
//irrelevant
}

/* Currently implemented syntax:
Order: walls, particles, struts
Colors: RED, GREEN, BLUE, INVISIBLE

Walls: (each wallBegin->wallEnd call creates a strip of connected walls)

"wallBegin
wallPoint,wallX,wallY
wallPoint,...
...
wallEnd"

"iceWallBegin
iceWallPoint...
iceWallEnd"

Particles:
"particlesBegin
particle,partX,partY,mass,radius,color
pinParticle,partX,partY,mass,radius,color
...
particlesEnd"

Struts:
"strutsBegin
strut,firstParticleIndex,secondParticleIndex,color
...
strutsEnd"



*/
String loadLevel(String filename){
  String[] buff;
  try{
    buff = loadStrings(filename);
  } catch (Exception e){
    System.out.println("File not found");
    return "";
  }
  
  String returnValue = "";
  for (int i=0; i<buff.length; i++){
    if (!(buff[i].length() > 1 && buff[i].charAt(0) == '/' && buff[i].charAt(1) == '/')) returnValue += buff[i] + "\n";
  }
  return returnValue;
}
  

void makeLevel(String filename){
  println("Loading "+filename);
  parseLevelString(loadLevel(filename));
  numWalls = myWall.size(); //myWall is list of all walls
  levelString = "";
}

void makeLevelFromString(String toParse){
  parseLevelString(toParse);
  numWalls = myWall.size();
  levelString = "";
}

void parseLevelString(String levelString){
  
  parseHeader(levelString);
  parseWalls(levelString);
  parseParticles(levelString);
  parseStruts(levelString);

}

void parseHeader(String levelString){
  //only one section of particle adds allowed, with no garbage inside it - otherwise things get real nasty here
  String[] newHeaders = levelString.split("headerBegin\n");
  if (newHeaders.length > 1) {
    newHeaders = newHeaders[1].split("headerEnd");
    String[] headerList = newHeaders[0].split("\n");
    int numHs = headerList.length;
    
    myPlayer = new Player(myParticle);
    myPlayer.rotate(-PI/2.0);
          
    for (int i=0; i<headerList.length; i++){
      String[] currentHeader = headerList[i].split(",");
      String toSet = currentHeader[0];
      float parameter = parseFloat(currentHeader[1]);
      if (toSet.equals("GRAVITY")){ gravityStrength = parameter;gravityForce = new Vector3d(0.0,gravityStrength,0);}
      else if (toSet.equals("GOALX")){ goalLocation.x = parameter;}
      else if (toSet.equals("GOALY")){ goalLocation.y = parameter;}
      else if (toSet.equals("PLAYERX")){
        myPlayer.translate(new Vector3d(parameter,0,0)); //default player position
      }
      else if (toSet.equals("PLAYERY")){
        myPlayer.translate(new Vector3d(0,parameter,0));
      }
      else if (toSet.equals("SPRINGCONSTANT")){
        springConstant = parameter;
      }
    }
 }  
}

void parseParticles(String levelString){
  otherParticle = new ArrayList();
  //only one section of particle adds allowed, with no garbage inside it - otherwise things get real nasty here
  String[] newParticles = levelString.split("particlesBegin\n");
  if (newParticles.length > 1) {newParticles = newParticles[1].split("particlesEnd");
  String[] particleList = newParticles[0].split("\n");
  int numPs = particleList.length;
  Particle[] parts = new Particle[numPs];
  for (int i=0; i<particleList.length; i++){
      String[] currentParticle = particleList[i].split(",");
      float xCoord = parseFloat(currentParticle[1]);
      float yCoord = parseFloat(currentParticle[2]);
      float pMass = parseFloat(currentParticle[3]);
      float pRad = parseFloat(currentParticle[4]);
      Vector3d pCol;
      if (currentParticle[5].equals("RED")){pCol = new Vector3d(255,0,0);}
      else if (currentParticle[5].equals("GREEN")){pCol = new Vector3d(0,255,0);}
      else if (currentParticle[5].equals("BLUE")){pCol = new Vector3d(0,0,255);}
      else{pCol = new Vector3d(255,255,255);}
      parts[i] = new Particle(new Vector3d(xCoord,yCoord,0),pMass,pRad,pCol);
      if (currentParticle[0].equals("pinParticle")){parts[i].setPinned();}
      parts[i].createID();
      otherParticle.add(parts[i]);
  }
 }
}

void parseStruts(String levelString){
  myStrut = new ArrayList();
  //depends on otherParticle array being already initialized and processed!
  String[] newStruts = levelString.split("strutsBegin\n");
  if (newStruts.length > 1) {newStruts = newStruts[1].split("strutsEnd");
  String[] strutList = newStruts[0].split("\n");
  int numStruts = strutList.length;
  Strut[] struts = new Strut[numStruts];
  int redStrutCount = 0;
  int greenStrutCount = 0;
  int blueStrutCount = 0;
  int whiteStrutCount = 0;
  for (int i=0; i<strutList.length; i++){
      String[] currentStrut = strutList[i].split(",");
      Particle partA = (Particle)otherParticle.get(parseInt(currentStrut[1]));
      Particle partB = (Particle)otherParticle.get(parseInt(currentStrut[2]));
      Vector3d pCol;
      boolean colored = false; boolean drawn = true;
      if (currentStrut[3].equals("RED")){pCol = new Vector3d(255,0,0);redStrutCount++;colored = true;}
      else if (currentStrut[3].equals("GREEN")){pCol = new Vector3d(0,255,0);greenStrutCount++;colored = true;}
      else if (currentStrut[3].equals("BLUE")){pCol = new Vector3d(0,0,255);blueStrutCount++;colored = true;}
      else if (currentStrut[3].equals("INVISIBLE")){pCol = new Vector3d(150,150,150); drawn = false; }
      else{pCol = new Vector3d(255,255,255);whiteStrutCount++;}
      struts[i] = new Strut(partA,partB);
      struts[i].strutColor = pCol;
      struts[i].createID();
      struts[i].setDraw(drawn);
      myStrut.add(struts[i]);
      if (colored && struts[i].pA.pinned && struts[i].pB.pinned) {myStaticCStruts.add(struts[i]);} //if both edges are pinned, add to static colliding list - change this bit if we allow collisions with uncolored struts!!!
      else if (colored) {myDynamicCStruts.add(struts[i]);}

  }
  redStruts = new Strut[redStrutCount];
  greenStruts = new Strut[greenStrutCount];
  blueStruts = new Strut[blueStrutCount];
  int redIndex = 0; int greenIndex = 0; int blueIndex = 0;
  for (int i=0; i<strutList.length; i++){
      String[] currentStrut = strutList[i].split(",");
      if (currentStrut[3].equals("RED")){redStruts[redIndex] = struts[i];redIndex++;}
      else if (currentStrut[3].equals("GREEN")){greenStruts[greenIndex] = struts[i];greenIndex++;}
      else if (currentStrut[3].equals("BLUE")){blueStruts[blueIndex] = struts[i];blueIndex++;}
  }
 }
 else{ redStruts = new Strut[0]; greenStruts = new Strut[0]; blueStruts = new Strut[0]; }
   
}

void parseWalls(String levelString){
  {
  String[] wallPaths = levelString.split("wallBegin\n");
  for (int j=0; j<wallPaths.length; j++){
    String[] commandList = wallPaths[j].split("\n");
    //println(levelString);
    int numWallPts=0;
    for (int i=0; i<commandList.length; i++){
      if (commandList[i].split(",")[0].equals("wallPoint")){
        numWallPts++;
      }
      if (commandList[i].split(",")[0].equals("wallEnd")){
        i=commandList.length;
      }
    }

    Vector3d[] wallVecs = new Vector3d[numWallPts];
    int wallIndex = 0;
    for (int i=0; i<commandList.length; i++){
      String[] currentCommand = commandList[i].split(",");
      //println(currentCommand[0]);
      if (currentCommand[0].equals("wallPoint")){
        float xCoord = parseFloat(currentCommand[1]);
        float yCoord = parseFloat(currentCommand[2]);
        wallVecs[wallIndex] = new Vector3d(xCoord,yCoord,0);
        wallIndex++;
      }
      if (currentCommand[0].equals("wallEnd")){
        i=commandList.length;
      }
    }
    wallList(wallVecs,myWall);  
  }
  }

  {//iceWall segment
  String[] wallPaths = levelString.split("iceWallBegin\n");
  for (int j=0; j<wallPaths.length; j++){
    String[] commandList = wallPaths[j].split("\n");
    //println(levelString);
    int numWallPts=0;
    for (int i=0; i<commandList.length; i++){
      if (commandList[i].split(",")[0].equals("iceWallPoint")){
        numWallPts++;
      }
      if (commandList[i].split(",")[0].equals("iceWallEnd")){
        i=commandList.length;
      }
    }

    Vector3d[] wallVecs = new Vector3d[numWallPts];
    int wallIndex = 0;
    for (int i=0; i<commandList.length; i++){
      String[] currentCommand = commandList[i].split(",");
      //println(currentCommand[0]);
      if (currentCommand[0].equals("iceWallPoint")){
        float xCoord = parseFloat(currentCommand[1]);
        float yCoord = parseFloat(currentCommand[2]);
        wallVecs[wallIndex] = new Vector3d(xCoord,yCoord,0);
        wallIndex++;
      }
      if (currentCommand[0].equals("iceWallEnd")){
        i=commandList.length;
      }
    }
    iceWallList(wallVecs,myWall);  
  }
  }
}
/*void iceWallList(Vector3d[] myPoints, ArrayList wallList){
 if (myPoints.length > 0){
 for (int i=1; i<myPoints.length; i++){
 wallList.add(new SolidWall2d(myPoints[i-1],myPoints[i],0.0,0.0,new Vector3d(0.0,0.0,255.0)));
 }
 }
 }*/
